﻿using CarPCBATest.Demo;
using Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Threading;

namespace CarPCBATest.Procedure
{
    public class FlashData : NotifyBase
    {
        private int _index;

        public int Index
        {
            get { return _index; }
            set
            {
                _index = value;
                this.DoNotify();
            }
        }

        private string _address;

        public string Address
        {
            get { return _address; }
            set
            {
                _address = value;
                this.DoNotify();
            }
        }

        private string _data;

        public string Data
        {
            get { return _data; }
            set
            {
                _data = value;
                this.DoNotify();
            }
        }
    }

    internal class TPS929120
    {
        public static List<byte[]> listWriteRegCmd = new List<byte[]>();
        public static List<byte[]> listReadRegCmd = new List<byte[]>();
        public static List<byte[]> listReadRegReturn = new List<byte[]>();
        public static List<string> listErr = new List<string>();

        /// <summary>
        /// 烧录EEPROM
        /// </summary>
        /// <param name="port">           端口 </param>
        /// <param name="eepromFilePath"> 烧录路径 </param>
        /// <param name="address">        地址 </param>
        /// <param name="onlyCompare">    是否只读 </param>
        /// <returns> </returns>
        private static bool WriteFlashBack(string port, string eepromFilePath, int address, bool onlyCompare, ref string checkCode)
        {
            // 打开串口
            SerialPort sp = new SerialPort();
            sp.BaudRate = 500000;
            sp.PortName = port;
            sp.DataBits = 8;
            sp.Parity = Parity.None;
            sp.StopBits = StopBits.One;
            listWriteRegCmd.Clear();
            listReadRegCmd.Clear();
            listReadRegReturn.Clear();
            listErr.Clear();
            try
            {
                // 读取 CSV 文件内容
                string[][] csvData = ReadCsvFile(eepromFilePath);
                byte mcuWriteAddress = (byte)(0x80 | (byte)(byte.Parse(address.ToString())));
                byte mcuReadAddress = (byte)(0x00 | (byte)(byte.Parse((address.ToString()))));
                // 添加通用指令

                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x61, 0x00 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x60, 0x07 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x00 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x02 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x01 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x09 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x02 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x09 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x63, 0x01 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x62, 0x80 }, 1, 3));

                //// 打印 CSV 数据
                foreach (string[] row in csvData)
                {
                    if (row[0].ToLower() == "address")
                        continue;
                    byte registerAddress = byte.Parse(row[0]);
                    byte value = byte.Parse(row[1]);
                    listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, registerAddress, value }, 1, 3));
                    listReadRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuReadAddress, registerAddress }, 1, 2));
                }
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x64, 0x04 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x62, 0x00 }, 1, 3));

                // 打开串口烧录
                sp.Open();

                if (!onlyCompare)
                {
                    //// 烧录
                    foreach (var item in listWriteRegCmd)
                    {
                        Mylog.Info("WriteMCUSend" + BitConverter.ToString(item).Replace("-", " "));
                        sp.Write(item, 0, item.Length);
                        Thread.Sleep(20);
                        byte[] dataRead = new byte[sp.BytesToRead];
                        sp.Read(dataRead, 0, sp.BytesToRead);
                        Mylog.Info("WriteMCUReturn:" + BitConverter.ToString(dataRead).Replace("-", " "));
                        if (dataRead.Length == item.Length)
                        {
                            throw new Exception("通信异常，请检查连接线");
                        }
                    }
                }
                Thread.Sleep(100);
                foreach (var item in listReadRegCmd)
                {
                    Mylog.Info("ReadMCUSend:" + BitConverter.ToString(item).Replace("-", " "));
                    sp.Write(item, 0, item.Length);
                    Thread.Sleep(20);
                    byte[] dataRead = new byte[sp.BytesToRead];
                    sp.Read(dataRead, 0, sp.BytesToRead);
                    Mylog.Info("ReadMCUReturn:" + BitConverter.ToString(dataRead).Replace("-", " ") + "<---read");
                    if (dataRead.Length == item.Length)
                    {
                        throw new Exception("通信异常");
                    }
                    listReadRegReturn.Add(dataRead);
                }

                //// 执行数据比对
                for (int i = 0; i < listReadRegReturn.Count; i++)
                {
                    //地址相同
                    if (listReadRegReturn[i][2] == listWriteRegCmd[i + 10][2])
                    {
                        if (listReadRegReturn[i][4] == listWriteRegCmd[i + 10][3])  // 数据相同
                        {
                            continue;
                        }
                        else
                        {
                            listErr.Add($"index[{i}]寄存器数据异常");
                        }
                    }
                    else
                    {
                        listErr.Add($"index[{i}]寄存器地址异常");
                    }
                }
                checkCode = listReadRegReturn.Last()[4].ToString("X2");
                sp.Close();
                sp.Dispose();
                if (listErr.Count > 0)
                {
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                listErr.Add(ex.Message);
                if (sp.IsOpen)
                {
                    sp.Close();
                    sp.Dispose();
                }
                return false;
            }
        }

        /// <summary>
        /// 烧录EEPROM
        /// </summary>
        /// <param name="port">           端口 </param>
        /// <param name="eepromFilePath"> 烧录路径 </param>
        /// <param name="address">        地址 </param>
        /// <param name="onlyCompare">    是否只读 </param>
        /// <returns> </returns>
        public static bool WriteFlash(string port, string eepromFilePath, int address, out int newAddress)
        {
            int tmpAddress = address;
            // 打开串口
            SerialPort sp = new SerialPort();
            sp.BaudRate = 500000;
            sp.PortName = port;
            sp.DataBits = 8;
            sp.Parity = Parity.None;
            sp.StopBits = StopBits.One;
            listWriteRegCmd.Clear();
            listReadRegCmd.Clear();
            listReadRegReturn.Clear();
            listErr.Clear();
            try
            {
                // 读取 CSV 文件内容
                string[][] csvData = ReadCsvFile(eepromFilePath);
                byte mcuWriteAddress = (byte)(0x80 | (byte)(byte.Parse(address.ToString())));
                byte mcuReadAddress = (byte)(0x00 | (byte)(byte.Parse((address.ToString()))));
                // 添加通用指令

                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x61, 0x00 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x60, 0x07 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x00 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x02 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x01 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x09 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x02 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x09 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x63, 0x01 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x62, 0x80 }, 1, 3));

                byte newMcuWriteAddress = (byte)(0x80 | (byte.Parse(address.ToString())));
                //// 打印 CSV 数据
                foreach (string[] row in csvData)
                {
                    if (row[0].ToLower() == "address")
                        continue;

                    byte registerAddress = byte.Parse(row[0]);
                    byte value = byte.Parse(row[1]);

                    //if (registerAddress == 0xC6)
                    //{
                    //    if (address < 8)
                    //    {
                    //        tmpAddress = address + value;
                    //        newMcuWriteAddress = (byte)(0x80 | (byte)(value + byte.Parse(address.ToString())));
                    //        Mylog.Info("新地址" + newMcuWriteAddress.ToString("X2"));
                    //    }
                    //    else
                    //    {
                    //        newMcuWriteAddress = (byte)(0x80 | (byte.Parse(address.ToString())));
                    //    }
                    //}

                    //if (registerAddress == 0xC7)
                    //{
                    //    mcuWriteAddress = newMcuWriteAddress;
                    //}

                    listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, registerAddress, value }, 1, 3));
                    listReadRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuReadAddress, registerAddress }, 1, 2));
                }
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x64, 0x04 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x62, 0x00 }, 1, 3));

                // 打开串口烧录
                sp.Open();
                {
                    //// 烧录

                    for (int i = 0; i < listWriteRegCmd.Count(); i++)
                    {
                        var item = listWriteRegCmd[i];
                        Console.WriteLine(BitConverter.ToString(item).Replace("-", " "));
                        sp.Write(item, 0, item.Length);
                        Thread.Sleep(10);
                        byte[] dataRead = new byte[sp.BytesToRead];
                        sp.Read(dataRead, 0, sp.BytesToRead);
                        Console.WriteLine(BitConverter.ToString(dataRead).Replace("-", " ") + "<---read");
                        Mylog.Info("write_send:" + BitConverter.ToString(item).Replace("-", " "));
                        Mylog.Info("write_recv:" + BitConverter.ToString(dataRead).Replace("-", " "));
                    }
                }
                newAddress = tmpAddress;
                sp.Close();
                sp.Dispose();
                if (listErr.Count > 0)
                {
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                listErr.Add(ex.Message);
                if (sp.IsOpen)
                {
                    sp.Close();
                    sp.Dispose();
                }
                newAddress = tmpAddress;
                return false;
            }
        }

        public static bool ReadFlash(string port, string eepromFilePath, int address, out string checkCode)
        {
            // 打开串口
            SerialPort sp = new SerialPort();
            sp.BaudRate = 500000;
            sp.PortName = port;
            sp.DataBits = 8;
            sp.Parity = Parity.None;
            sp.StopBits = StopBits.One;
            listWriteRegCmd.Clear();
            listReadRegCmd.Clear();
            listReadRegReturn.Clear();
            listErr.Clear();
            try
            {
                // 读取 CSV 文件内容
                string[][] csvData = ReadCsvFile(eepromFilePath);
                byte mcuWriteAddress = (byte)(0x80 | (byte)(byte.Parse(address.ToString())));
                byte mcuReadAddress = (byte)(0x00 | (byte)(byte.Parse((address.ToString()))));
                // 添加通用指令

                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x61, 0x00 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x60, 0x07 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x00 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x02 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x01 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x09 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x02 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x65, 0x09 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x63, 0x01 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x62, 0x80 }, 1, 3));

                //// 打印 CSV 数据
                foreach (string[] row in csvData)
                {
                    if (row[0].ToLower() == "address")
                        continue;
                    byte registerAddress = byte.Parse(row[0]);
                    byte value = byte.Parse(row[1]);

                    listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, registerAddress, value }, 1, 3));
                    listReadRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuReadAddress, registerAddress }, 1, 2));
                }
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x64, 0x04 }, 1, 3));
                listWriteRegCmd.Add(CRC8Maxim.AppendChecksum(new byte[] { 0x55, mcuWriteAddress, 0x62, 0x00 }, 1, 3));

                // 打开串口烧录
                sp.Open();

                foreach (var item in listReadRegCmd)
                {
                    Console.WriteLine(BitConverter.ToString(item).Replace("-", " "));
                    sp.Write(item, 0, item.Length);
                    Thread.Sleep(10);
                    byte[] dataRead = new byte[sp.BytesToRead];
                    sp.Read(dataRead, 0, sp.BytesToRead);
                    Console.WriteLine(BitConverter.ToString(dataRead).Replace("-", " ") + "<---read");
                    if (dataRead.Length == item.Length)
                    {
                        throw new Exception("通信异常");
                    }
                    Mylog.Info("read send:" + BitConverter.ToString(item).Replace("-", " "));
                    Mylog.Info("read recv:" + BitConverter.ToString(dataRead).Replace("-", " "));
                    listReadRegReturn.Add(dataRead);
                }

                //// 执行数据比对
                for (int i = 0; i < listReadRegReturn.Count; i++)
                {
                    //地址相同
                    if (listReadRegReturn[i][2] == listWriteRegCmd[i + 10][2])
                    {
                        if (listReadRegReturn[i][4] == listWriteRegCmd[i + 10][3])  // 数据相同
                        {
                            continue;
                        }
                        else
                        {
                            listErr.Add($"index[{i}]寄存器数据异常");
                        }
                    }
                    else
                    {
                        listErr.Add($"index[{i}]寄存器地址异常");
                    }
                }
                checkCode = listReadRegReturn.Last()[4].ToString("X2");
                sp.Close();
                sp.Dispose();
                if (listErr.Count > 0)
                {
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                listErr.Add(ex.Message);
                if (sp.IsOpen)
                {
                    sp.Close();
                    sp.Dispose();
                }
                checkCode = "00";
                return false;
            }
        }

        private static string[][] ReadCsvFile(string eepromFilePath)
        {
            if (!File.Exists(eepromFilePath))
                throw new Exception($"未找到文件[{eepromFilePath}]");
            // 读取 CSV 文件的所有行
            string[] lines = File.ReadAllLines(eepromFilePath);

            // 创建一个二维字符串数组来存储 CSV 数据
            string[][] csvData = new string[lines.Length][];

            // 解析每一行并存储到数组中
            for (int i = 0; i < lines.Length; i++)
            {
                csvData[i] = lines[i].Split(',');
            }

            return csvData;
        }
    }
}